package com.wys.spring.swagger.plugin;


import com.wys.spring.SpringCommonProperties;
import com.wys.utils.JsonUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import springfox.documentation.service.ListVendorExtension;
import springfox.documentation.service.VendorExtension;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.OperationBuilderPlugin;
import springfox.documentation.spi.service.contexts.OperationContext;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class DynamicParamBuilderPlugin implements OperationBuilderPlugin {

    public static final String IGNORE_PARAMETER_EXTENSION_NAME = "x-ignoreParameters";

    public static final String INCLUDE_PARAMETER_EXTENSION_NAME = "x-includeParameters";
    private static final Logger log = LoggerFactory.getLogger(DynamicParamBuilderPlugin.class);

    private SpringCommonProperties springCommonProperties;

    public DynamicParamBuilderPlugin(SpringCommonProperties springCommonProperties) {
        this.springCommonProperties = springCommonProperties;
    }

    @Override
    public void apply(OperationContext context) {
        if (ObjectUtils.isNotEmpty(springCommonProperties.getSwagger()) && ObjectUtils.isNotEmpty(springCommonProperties.getSwagger().getIgnoreParameters())) {
            List<SpringCommonProperties.SwaggerDynamicParameter> dynamicParameterList = springCommonProperties.getSwagger().getIgnoreParameters().stream().filter(s -> StringUtils.isNotBlank(s.getPath()) && context.requestMappingPattern().startsWith(s.getPath().replace("*", ""))).collect(Collectors.toList());
            if (springCommonProperties.getLogging().getRequestEnable()) {
                log.warn("需要排除的接口:{},动态值:{}", context.requestMappingPattern(), JsonUtils.object2Json(dynamicParameterList));
            }
            addExtensionParameters(buildMap(dynamicParameterList), IGNORE_PARAMETER_EXTENSION_NAME, context);
        }
        if (ObjectUtils.isNotEmpty(springCommonProperties.getSwagger()) && ObjectUtils.isNotEmpty(springCommonProperties.getSwagger().getIncludeParameters())) {
            List<SpringCommonProperties.SwaggerDynamicParameter> dynamicParameter = springCommonProperties.getSwagger().getIncludeParameters().stream().filter(s -> StringUtils.isNotBlank(s.getPath()) && context.requestMappingPattern().startsWith(s.getPath().replace("*", ""))).collect(Collectors.toList());
            if (springCommonProperties.getLogging().getRequestEnable()) {
                log.warn("需要新增的接口:{},动态值:{}", context.requestMappingPattern(), JsonUtils.object2Json(dynamicParameter));
            }
            addExtensionParameters(buildMap(dynamicParameter), INCLUDE_PARAMETER_EXTENSION_NAME, context);
        }
    }

    @Override
    public boolean supports(DocumentationType delimiter) {
        return true;
    }

    public Map<String, Boolean> buildMap(List<SpringCommonProperties.SwaggerDynamicParameter> dynamicParameterList) {
        Map<String, Boolean> map = new HashMap<>();
        if (ObjectUtils.isNotEmpty(dynamicParameterList)) {
            dynamicParameterList.forEach(d -> map.putAll(d.getDynamicValue()));
        }
        return map;
    }

    /**
     * 添加扩展属性参数
     *
     * @param map           参数
     * @param extensionName 扩展名称
     * @param context       上下文
     */
    private void addExtensionParameters(Map<String, Boolean> map, String extensionName, OperationContext context) {
        if (ObjectUtils.isNotEmpty(map)) {
            List<Map<String, Boolean>> maps = new ArrayList<>();
            maps.add(map);
            ListVendorExtension<Map<String, Boolean>> listVendorExtension = new ListVendorExtension<>(extensionName, maps);
            List<VendorExtension> vendorExtensions = new ArrayList<>();
            vendorExtensions.add(listVendorExtension);
            context.operationBuilder().extensions(vendorExtensions);
        }

    }

}
